#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#define LEFT "["
#define RIGHT "]"
#define LABLE "#"
#define DELIM " \t"
#define LINE_SIZE 1024
#define ARGC_SIZE 32
#define EXIT_CODE 44
char pwd[LINE_SIZE];
extern char**environ;
char*argv[ARGC_SIZE];
char commandline[LINE_SIZE];
int quit=0;
int last_code=0;
char myenv[LINE_SIZE];
const char*getusername(){
    return getenv("USER");
}
const char* gethostname(){
    return getenv("HOSTNAME");
}
void getpwd(){
    getcwd(pwd,sizeof(pwd));
}

void Interact(char*cline,int size){
    getpwd();
    printf(LEFT"%s@%s %s"RIGHT""LABLE" ",getusername(),gethostname(),pwd);       
    char *s=fgets(cline,size,stdin);
    cline[strlen(cline)-1]='\0';
    assert(s);
    (void)s;

}
int splitstring(char commandline[],char*argv[]){

    int i=0;
    argv[i++]=strtok(commandline,DELIM);
    while(argv[i++]=strtok(NULL,DELIM));
    return i-1;
}
void normalExe(char*argv[]){
       pid_t id=fork();
       if(id<0){
        perror("fork");
        return;
       }
       else if(id==0){
            execvp(argv[0],argv);
            //execvpe(argv[0],argv,environ);
            exit(EXIT_CODE);
       }
       else{
           int status=0;
           pid_t ret=waitpid(id,&status,0);
           if(ret==id){
               last_code=WEXITSTATUS(status);
           }
       }

}
int buildcommand(char*_argv[],int _argc){
        if(_argc==2&&strcmp(_argv[0],"cd")==0){
            chdir(_argv[1]);
            getpwd();
            sprintf(getenv("PWD"),"%s",pwd);
            return 1;
        }
        else if(_argc==2&&strcmp(_argv[0],"export")==0){
            strcpy(myenv,_argv[1]);
            putenv(myenv);
            return 1;
        }
        else if(_argc==2&&strcmp(_argv[0],"echo")==0){
            if(strcmp(_argv[1],"$?")==0){
                printf("%d\n",last_code);
                last_code=0;
                return 1;
            }
            if(*_argv[1]=='$'){
                char*val=getenv(_argv[1]+1);
                if(val)printf("%s\n",val);
            }
            else{
                printf("%s\n",_argv[1]);
            }
            return 1;
        }
        if(strcmp(_argv[0],"ls")==0){
            _argv[_argc++]="--color";
            _argv[_argc]=NULL;
        }
        return 0;

}
int main(){
    while(!quit){
        Interact(commandline,sizeof(commandline));
        int argc=splitstring(commandline,argv);
        if(argc==0){
            continue;
        }
       // for(int i=0;i<argc;i++)printf("[%d]:%s\n",i,argv[i]);
        int n=buildcommand(argv,argc);
        if(!n)normalExe(argv);
        
    }
    return 0;
}
